package jdklearning.concurrent.thread;


import java.util.concurrent.locks.LockSupport;

/**
 * LockSupport是用来创建锁和其他同步类的基本线程阻塞原语
 * 。LockSupport 提供park()和unpark()方法实现阻塞线程和解除线程阻塞
 * ，LockSupport和每个使用它的线程都与一个许可(permit)关联
 * 。permit相当于1，0的开关，默认是0，调用一次unpark就加1变成1
 * ，调用一次park会消费permit, 也就是将1变成0，同时park立即返回
 * 。再次调用park会变成block（因为permit为0了，会阻塞在这里，直到permit变为1）
 * , 这时调用unpark会把permit置为1。每个线程都有一个相关的permit, permit最多只有一个
 * ，重复调用unpark也不会积累。
 *
 * park()和unpark()不会有 “Thread.suspend和Thread.resume所可能引发的死锁” 问题
 * ，由于许可的存在，调用 park 的线程和另一个试图将其 unpark 的线程之间的竞争将保持活性。
 *
 * 如果调用线程被中断，则park方法会返回。同时park也拥有可以设置超时时间的版本。
 * @author shenenlu 2021年02月10日 下午17:41:40
 */
public class ParkAndUnPark {


    public static void testPark(){
        Thread t = new Thread(() -> {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            LockSupport.park();
        });
        t.setDaemon(false);
        t.start();
        LockSupport.unpark(t);
    }



    public static void testInterruptPark() throws InterruptedException {
        Thread t = new Thread(() -> {
            while (true){
                System.out.println(Thread.currentThread().isInterrupted());
                LockSupport.park();
//                System.out.println(Thread.currentThread().isInterrupted());
//                try {
//                    Thread.sleep(2000);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
            }
        });
        t.setDaemon(false);

        t.start();
        Thread.sleep(100);
        t.interrupt();


    }



    public static void main(String[] args) throws InterruptedException {
        testInterruptPark();

    }

}
